#pragma once

#include <boost/noncopyable.hpp>
#include <boostext/signal.hpp>

#include "win_exports.hpp"




namespace WinUi
{
	class WINUI_API Application : public boost::noncopyable
	{
	public:

		typedef boost::signals2::signal<void()>   notification;

	private:

		static Application* m_theApp;

	private:

		/// Flag that defines if the queue shall employ fast pumping or not
		bool   m_fastPumping;

		/// Flag that defines if the application is the active one or not
		bool   m_active;

	protected:

		/// This signal is emitted whenever the application has nothing to process
		notification   m_idle;

		/// This signal is emitted whenever the application is activated
		notification   m_activated;

		/// This signal is emitted whenever the application is deactivated
		notification   m_deactivated;

	public:

		/// Allows other to simply connect a slot with a signal: theApp.activated.connect(&f);
		boostext::connector<notification>   idle;
		boostext::connector<notification>   activated;
		boostext::connector<notification>   deactivated;

	public:

		Application(const char* cmdLine);
		Application(int argc, const char* const* argv);
		virtual ~Application();



		/**
		 * Enabled fast pumping.
		 * This directly influences the frequency, idle() is emitted.
		 */
		void setFastPumping(bool b = true);

		/**
		 * Test if fast pumping is enabled.
		 */
		bool fastPumping() const;

		/**
		 * Tests if the application is active or not.
		 */
		bool active() const;



		/**
		 * This function starts the message loop.
		 * Translates and dispatches all message to the appropriate
		 * windows.
		 *
		 * @return   the exit code for the application
		 */
		int exec();



		/**
		 * Sets the application to be active.
		 * Must be called from a window to work.
		 */
		void activate();

		/**
		 * Sets the application to be inactive.
		 */
		void deactivate();



		/**
		 * Terminates the application.
		 * The application is not terminated immediately,
		 * instead a WM_QUIT message is posted onto the queue,
		 * so the application will quit, once the message is
		 * processed.
		 *
		 * @param code   the return code for the application
		 */
		static void quit(int exitCode);

		/**
		 * Quits the application with exitCode = 0.
		 */
		static void exit();

		/**
		 * Get a reference to the only Application instance.
		 */
		static Application& instance();

		/**
		 * Enable the Visual Style, employed by the Operating System.
		 * Otherwise you will get boring grey, hard-edged buttons.
		 */
		static void initGui();

		/**
		 * Display a messagebox with the given title and text.
		 * The messagebox only contains an OK button.
		 */
		static void messageBox(const std::string& title, const std::string& message);
	};
	///////////////////////////////////////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////////////////////////////
